home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp95 / gnuchess.arc / piece.c < prev    next >
C/C++ Source or Header  |  1992-01-16  |  32KB  |  1,543 lines

  1. /**********************************************************************/
  2. /*   Following  code  copied  from  nuxdsp.c  and modified a lot for  */
  3. /*   the  small  16x40 screen of the HP95. Also added lots of screen  */
  4. /*   optimisations  because  the  HP95  is slow at screen access and  */
  5. /*   for  short  thinking times, the time is dominated by the screen  */
  6. /*   update.                                  */
  7. /*                                         */
  8. /*   Written  by  Paul  Fox and hereby placed under terms of the GNU  */
  9. /*   general license. (January 1992)                      */
  10. /**********************************************************************/
  11.  
  12. #include <ctype.h>
  13. #include <signal.h>
  14. # if defined(MSDOS)
  15. #    include <dos.h>
  16. #    include <conio.h>
  17. # else
  18. #     define     cdecl
  19. #    define    huge
  20. #    define    far
  21. #    define    kbhit()    1
  22. #    define    getch() getchar()
  23. # endif
  24. #include "hp95.h"
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <time.h>
  28. #include    "gnuchess.h"
  29.  
  30. #define ESC 0x1B
  31. #define refresh() fflush(stdout)
  32.  
  33. /**********************************************************************/
  34. /*   Line numbers (starting from zero) where certain messages go.     */
  35. /**********************************************************************/
  36. # define    LINE_TOP_PIECES    1
  37. # define    LINE_DEPTH    2
  38. # define    LINE_MAX_TREE    8
  39. # define    LINE_YOUR_GO    13
  40. # define    LINE_BOT_PIECES    14
  41. # define    MAX_LINES    16
  42.  
  43. int    ttcol;
  44. int    ttrow;
  45. int    ttwidth[MAX_LINES];
  46.  
  47. struct bitmap {
  48.     G_AREA    info;
  49.     char    bits[30];
  50.     };
  51. struct bitmap bitmap[] = {
  52. # include    "pieces.bm"
  53.     };
  54. struct bitmap *w_on_b_piece[] = {
  55.   &bitmap[0], 
  56.   &bitmap[1], &bitmap[2], &bitmap[3], &bitmap[4], &bitmap[5], &bitmap[6] 
  57.   };
  58. struct bitmap *w_on_w_piece[] = {
  59.   &bitmap[7], 
  60.   &bitmap[8], &bitmap[9], &bitmap[10], &bitmap[11], &bitmap[12], &bitmap[13] 
  61.   };
  62. struct bitmap *b_on_w_piece[] = {
  63.   &bitmap[14], 
  64.   &bitmap[15], &bitmap[16], &bitmap[17], &bitmap[18], &bitmap[19], &bitmap[20] 
  65.   };
  66. struct bitmap *b_on_b_piece[] = {
  67.   &bitmap[21], 
  68.   &bitmap[22], &bitmap[23], &bitmap[24], &bitmap[25], &bitmap[26], &bitmap[27] 
  69.   };
  70. # define    TAB    21
  71.  
  72. char    pxx[] = " PNBRQK";
  73. char    qxx[] = " pnbrqk";
  74. char    rxx[] = "12345678";
  75. char    cxx[] = "abcdefgh";
  76. #define VIR_C(s)  ((flag.reverse) ? 7-column(s) : column(s))
  77. #define VIR_R(s)  ((flag.reverse) ? 7-row(s) : row(s))
  78. #define Vblack(s) (!((VIR_C(s) + VIR_R(s)) % 2))
  79. static char mvstr[4][6];
  80. static char* ColorStr[2] = {"White", "Black"};
  81. static long evrate;
  82. short PositionFlag = 0;
  83. short coords = 1;
  84.  
  85. static void param (short n);
  86. void TerminateSearch (int), Die (int);
  87. void    draw_bitmap();
  88. void    draw_piece(int, int,  struct bitmap *);
  89. long    read_number(long);
  90. void    read_line(char *);
  91.  
  92. void
  93. Initialize(void)
  94. {
  95.     ClrScreen();
  96.     gotoXY(0, 0);
  97.     G_Mode(G_GRAPHICS);
  98.     gotoXY(5, 5);
  99.     printz("GNU CHESS 3.1 FOR THE HP95");
  100.     gotoXY(5, 7);
  101.     printz("  RELEASE 1.02 BY PAUL FOX");
  102.     refresh();
  103.     signal(SIGINT, Die);
  104. }
  105. void
  106. ExitChess (void)
  107. {
  108.     ListGame ();
  109.     G_Mode(G_ALPHA);
  110.     gotoXY(0, 15);
  111.     printf("\n\n");
  112.     exit (0);
  113. }
  114. char *
  115. count_pieces(short side)
  116. {    register int    i;
  117.     static char    buf[20];
  118.     char    *cp;
  119.  
  120.     cp = buf;
  121.     if (side == white)
  122.         i = 1;
  123.     else
  124.         i = 2;
  125.     for ( ; i <= GameCnt; i += 2) {
  126.         if (GameList[i].piece)
  127.             *cp++ = pxx[GameList[i].piece];
  128.         }
  129.     *cp = '\0';
  130.     return buf;
  131. }
  132. void
  133. read_line(str)
  134. char    *str;
  135. {    char    *cp = str;
  136.     int    ch;
  137.     int    counter;
  138.     char    cursor_type = '_';
  139.  
  140.     while (1) {
  141.         *cp = '\0';
  142.         counter = 0;
  143.         write(1, &cursor_type, 1);
  144.         while (1) {
  145.             if (kbhit())
  146.                 break;
  147.             if (counter == 0) {
  148.                 write(1, "\b \b", 3);
  149.                 write(1, &cursor_type, 1);
  150.                 }
  151.             if (counter++ < 40)
  152.                 continue;
  153.             counter = 0;
  154.             if (cursor_type == '_')
  155.                 cursor_type = ' ';
  156.             else
  157.                 cursor_type = '_';
  158.             }
  159.         write(1, "\b \b", 3);
  160.         ch = getch();
  161.         if (ch == 0) {
  162.             getch();
  163.             continue;
  164.             }
  165.         if (ch == '\b' || ch == 0x7f) {
  166.             if (cp > str) {
  167.                 ttwidth[ttrow]--;
  168.                 cp--;
  169.                 write(1, "\b \b", 3);
  170.                 }
  171.             continue;
  172.             }
  173.         if (ch == '\n' || ch == '\r')
  174.             return;
  175.         *cp = ch;
  176.         write(1, cp++, 1);
  177.         ttwidth[ttrow]++;
  178.         }
  179. }
  180. long
  181. read_number(val)
  182. long    val;
  183. {    char    s[80];
  184.  
  185.     read_line(s);
  186.     if (s[0] == '\0')
  187.         return val;
  188.     return atoi(s);
  189. }
  190. void
  191. Die (int Sig)
  192. {
  193.   char s[80];
  194.  
  195.   signal (SIGINT, SIG_IGN);
  196.   Sig++;                /* shut up the compiler */
  197.   ShowMessage ("Abort? ");
  198.   read_line(s);
  199.   if (strcmp (s, "yes") == 0)
  200.     ExitChess ();
  201.   signal (SIGINT, Die);
  202. }
  203. void
  204. TerminateSearch (int Sig)
  205. {
  206.   signal (SIGINT, SIG_IGN);
  207.   Sig++;                /* shut up the compiler */
  208.   flag.timeout = true;
  209.   flag.bothsides = false;
  210.   signal (SIGINT, Die);
  211. }
  212. void
  213. algbr (short int f, short int t, short int flag)
  214.  
  215. /*
  216.    Generate move strings in different formats.
  217. */
  218.  
  219. {
  220.   int m3p;
  221.  
  222.   if (f != t)
  223.     {
  224.       /* algebraic notation */
  225.       mvstr[0][0] = cxx[column (f)];
  226.       mvstr[0][1] = rxx[row (f)];
  227.       mvstr[0][2] = cxx[column (t)];
  228.       mvstr[0][3] = rxx[row (t)];
  229.       mvstr[0][4] = mvstr[3][0] = '\0';
  230.       if ((mvstr[1][0] = pxx[board[f]]) == 'P')
  231.     {
  232.       if (mvstr[0][0] == mvstr[0][2])    /* pawn did not eat */
  233.         {
  234.           mvstr[2][0] = mvstr[1][0] = mvstr[0][2];    /* to column */
  235.           mvstr[2][1] = mvstr[1][1] = mvstr[0][3];    /* to row */
  236.           m3p = 2;
  237.         }
  238.       else
  239.         /* pawn ate */
  240.         {
  241.           mvstr[2][0] = mvstr[1][0] = mvstr[0][0];    /* from column */
  242.           mvstr[2][1] = mvstr[1][1] = mvstr[0][2];    /* to column */
  243.           mvstr[2][2] = mvstr[0][3];
  244.           m3p = 3;        /* to row */
  245.         }
  246.       mvstr[2][m3p] = mvstr[1][2] = '\0';
  247.       if (flag & promote)
  248.         {
  249.           mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  250.           mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  251.         }
  252.     }
  253.       else
  254.     /* not a pawn */
  255.     {
  256.       mvstr[2][0] = mvstr[1][0];
  257.       mvstr[2][1] = mvstr[0][1];
  258.       mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  259.       mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  260.       mvstr[2][4] = mvstr[1][3] = '\0';
  261.       strcpy (mvstr[3], mvstr[2]);
  262.       mvstr[3][1] = mvstr[0][0];
  263.       if (flag & cstlmask)
  264.         {
  265.           if (t > f)
  266.         {
  267.           strcpy (mvstr[1], "o-o");
  268.           strcpy (mvstr[2], "O-O");
  269.         }
  270.           else
  271.         {
  272.           strcpy (mvstr[1], "o-o-o");
  273.           strcpy (mvstr[2], "O-O-O");
  274.         }
  275.         }
  276.     }
  277.     }
  278.   else
  279.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  280. }
  281.  
  282. int
  283. VerifyMove (char *s, short int iop, short unsigned int *mv)
  284.  
  285. /*
  286.    Compare the string 's' to the list of legal moves available for the
  287.    opponent. If a match is found, make the move on the board.
  288. */
  289.  
  290. {
  291.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  292.   static struct leaf xnode;
  293.   struct leaf *node;
  294.  
  295.   *mv = 0;
  296.   if (iop == 2)
  297.     {
  298.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  299.       return (false);
  300.     }
  301.   cnt = 0;
  302.   MoveList (opponent, 2);
  303.   pnt = TrPnt[2];
  304.   while (pnt < TrPnt[3])
  305.     {
  306.       node = &Tree[pnt++];
  307.       algbr (node->f, node->t, (short) node->flags);
  308.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  309.       strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  310.     {
  311.       cnt++;
  312.       xnode = *node;
  313.     }
  314.     }
  315.   if (cnt == 1)
  316.     {
  317.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  318.       if (SqAtakd (PieceList[opponent][0], computer))
  319.     {
  320.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  321.       ShowMessage ("Illegal Move!!");
  322.       return (false);
  323.     }
  324.       else
  325.     {
  326.       if (iop == 1)
  327.         return (true);
  328.       UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
  329.       if ((board[xnode.t] == pawn)
  330.           || (xnode.flags & capture)
  331.           || (xnode.flags & cstlmask))
  332.         {
  333.           Game50 = GameCnt;
  334.           ZeroRPT ();
  335.         }
  336.       GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  337.       GameList[GameCnt].nodes = 0;
  338.       ElapsedTime (1);
  339.       GameList[GameCnt].time = (short) et;
  340.       TimeControl.clock[opponent] -= et;
  341.       --TimeControl.moves[opponent];
  342.       *mv = (xnode.f << 8) | xnode.t;
  343.       algbr (xnode.f, xnode.t, false);
  344.       return (true);
  345.     }
  346.     }
  347.   if (cnt > 1)
  348.     ShowMessage ("Ambiguous Move!");
  349.   return (false);
  350. }
  351. void
  352. help (void)
  353. {
  354.   ClrScreen ();
  355.   printz ("g1f3 or Nf3   move from g1->f3 or N->f3\n");
  356.   printz ("quit     Exit Chess\n");
  357.   printz ("beep     on/off\n");
  358.   printz ("o-o or o-o-o  castle king/queen side\n");
  359.   printz ("easy     on/off\n");
  360.   printz ("hash     on/off\n");
  361.   printz ("bd       redraw board\n");
  362.   printz ("reverse  board display\n");
  363.   printz ("list     game to chess.lst\n");
  364.   printz ("book     on/off\n");
  365.   printz ("undo     undo last ply\n");
  366.   printz ("remove   take back a move\n");
  367.   printz ("edit     edit board\n");
  368.   printz ("force    enter game moves\n");
  369.   printz ("   Hit <Enter> to continue...");
  370.   while (getchar() != '\n')
  371.       ;
  372.  
  373.   ClrScreen ();
  374.   printz ("switch   sides with computer\n");
  375.   printz ("both     computer match\n");
  376.   printz ("white    computer plays white\n");
  377.   printz ("black    computer plays black\n");
  378.   printz ("depth    set search depth\n");
  379.   printz ("level    select level\n");
  380.   printz ("post     principle variation\n");
  381.   printz ("hint     suggest a move\n");
  382.   printz ("save     game to file\n");
  383.   printz ("get      game from file\n");
  384.   printz ("random   randomize play\n");
  385.   printz ("new      start new game\n");
  386.   printz ("coords   toggle coords\n");
  387.   printz ("p        show coordinate values\n");
  388.   printz ("   Hit <Enter> to continue...");
  389.   while (getchar() != '\n')
  390.       ;
  391.  
  392.   ClrScreen ();
  393.   printz ("Computer: %s\n", ColorStr[computer]);
  394.   printz ("Opponent: %s\n", ColorStr[opponent]);
  395.   printz ("Level: %ld\n", Level);
  396.   printz ("Easy mode: %s\n", (flag.easy) ? "ON" : "OFF");
  397.   printz ("Depth: %d\n", MaxSearchDepth);
  398.   printz ("Random: %s\n", (dither) ? "ON" : "OFF");
  399.   printz ("Transposition table: %s\n\n", (flag.hash) ? "ON" : "OFF");
  400.   printz ("   Hit <Enter> to continue...");
  401.   while (getchar() != '\n')
  402.       ;
  403.   ClrScreen ();
  404.   UpdateDisplay (0, 0, 1, 0);
  405. }
  406. void
  407. EditBoard (void)
  408.  
  409. /*
  410.   Set up a board position. Pieces are entered by typing the piece
  411.   followed by the location. For example, Nf3 will place a knight on
  412.   square f3.
  413. */
  414.  
  415. { register short sq;
  416.   short a, r, c, i;
  417.   char s[80];
  418.  
  419.   ClrScreen ();
  420.   UpdateDisplay (0, 0, 1, 0);
  421.   gotoXY (TAB, 3);
  422.   printz (".   Exit to main");
  423.   gotoXY (TAB, 4);
  424.   printz ("#   Clear board");
  425.   gotoXY (TAB, 5);
  426.   printz ("c   Change sides");
  427.   gotoXY (TAB, 7);
  428.   printz ("Piece+loc: ");
  429.   a = white;
  430.   do
  431.     {
  432.       gotoXY (TAB, 6);
  433.       printz ("Editing: %s", ColorStr[a]);
  434.       gotoXY (TAB + 12, 7);
  435.       ClrEoln ();
  436.       read_line(s);
  437.       if (s[0] == '#')
  438.     {
  439.       for(sq = 0; sq < 64; sq++)
  440.         {
  441.           board[sq] = no_piece;
  442.           color[sq] = neutral;
  443.           DrawPiece (sq);
  444.         }
  445.     }
  446.       if (s[0] == 'c' || s[0] == 'C')
  447.     a = otherside[a];
  448.       c = s[1] - 'a';
  449.       r = s[2] - '1';
  450.       if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
  451.     {
  452.       sq = locn (r, c);
  453.       for (i = king; i > no_piece; i--)
  454.         if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
  455.           break;
  456.       board[sq] = i;
  457.       color[sq] = (board[sq] == no_piece) ? neutral : a;    
  458.       DrawPiece (sq);
  459.     }
  460.   } while (s[0] != '.');
  461.  
  462.   for (sq = 0; sq < 64; sq++)
  463.     Mvboard[sq] = (board[sq] != Stboard[sq]) ? 10 : 0;
  464.   GameCnt = 0;
  465.   Game50 = 1;
  466.   ZeroRPT ();
  467.   Sdepth = 0;
  468.   InitializeStats ();
  469.   ClrScreen ();
  470.   UpdateDisplay (0, 0, 1, 0);
  471. }
  472.  
  473. void
  474. ShowPlayers (void)
  475. {    int    y;
  476. static char gnu[] = "GNU CHESS 3.1 MAR 90";
  477. static char human[] = "Human";
  478.  
  479.     if (flag.reverse)
  480.         y = 15;
  481.     else
  482.         y = 0;
  483.     draw_small_string(TAB * FONT_WIDTH, y * FONT_HEIGHT, 
  484.         computer == black ? gnu : human);
  485.     if (flag.reverse)
  486.         y = 0;
  487.     else
  488.         y = 15;
  489.     draw_small_string(TAB * FONT_WIDTH, y * FONT_HEIGHT, 
  490.         computer == white ? gnu : human);
  491. }
  492.  
  493. void
  494. ShowDepth (char ch)
  495. {
  496.   gotoXY (TAB, LINE_DEPTH);
  497.   printz ("Depth=%2d%c", Sdepth, ch);
  498. }
  499.  
  500. void
  501. ShowScore (short score)
  502. {
  503.   gotoXY (TAB + 10, LINE_DEPTH);
  504.   printz ("Sc=%d", score);
  505.   ClrEoln ();
  506. }
  507.  
  508. void
  509. ShowMessage (char *s)
  510. {
  511.   gotoXY (TAB, 12);
  512.   printz ("%s", s);
  513.   ClrEoln ();
  514. }
  515.  
  516. void
  517. ClearMessage (void)
  518. {
  519.   gotoXY (TAB, LINE_YOUR_GO);
  520.   ClrEoln ();
  521. }
  522.  
  523. void
  524. ShowCurrentMove (short int pnt, short int f, short int t)
  525. {
  526.   if (Sdepth < 3)
  527.       return;
  528.  
  529.   algbr (f, t, false);
  530.   gotoXY (TAB, 4);
  531.   printz ("(%2d) %4s", pnt, mvstr[0]);
  532. }
  533.  
  534. void
  535. ShowSidetomove (void)
  536. {
  537.     OutputMove();
  538. /*
  539.   gotoXY (TAB, 9);
  540.   printz ("%2d:   %s", 1 + GameCnt / 2, ColorStr[player]);
  541.   ClrEoln ();
  542. */
  543. }
  544.  
  545. void
  546. ShowPrompt (void)
  547. {
  548.   gotoXY (TAB, LINE_YOUR_GO);
  549.   printz ("Your go? ");
  550.   ClrEoln ();
  551. }
  552.  
  553. void
  554. ShowNodeCnt (long int NodeCnt, long int evrate)
  555. {      
  556.   gotoXY (TAB, 3);
  557.   printz ("N=%ld N/Sec=%d", NodeCnt, (int) evrate);
  558.   ClrEoln ();
  559. }  
  560.  
  561. void
  562. ShowResults (short int score, short unsigned int *bstline, char ch)
  563. {
  564.   unsigned char d, ply;
  565.   int    col;
  566.  
  567.   if (flag.post == 0)
  568.       return;
  569.     
  570.   /***********************************************/
  571.   /*   Dont  update  screen for first couple of  */
  572.   /*   levels   because   score   changes   too  */
  573.   /*   quickly  and  uses  up more CPU than the  */
  574.   /*   thinking time.                 */
  575.   /***********************************************/
  576.   if (Sdepth < 3)
  577.       return;
  578.  
  579.       col = 3;
  580.       ShowDepth (ch);
  581.       ShowScore (score);
  582.       d = 4;
  583.       for (ply = 1; bstline[ply] > 0; ply++)
  584.     {
  585.       if (col == 3) {
  586.           gotoXY (TAB, ++d);
  587.           ClrEoln ();
  588.           col = 0;
  589.         }
  590.       algbr ((short) bstline[ply] >> 8, (short) bstline[ply] & 0xFF, false);
  591.       printz ("%5s ", mvstr[0]);
  592.       col++;
  593.     }
  594.       ClrEoln ();    
  595.       while (d < 8)
  596.     {
  597.       gotoXY (TAB, ++d);
  598.       ClrEoln ();
  599.     }
  600. }
  601.  
  602. void
  603. SearchStartStuff (short int side)
  604. {
  605.   short i;
  606.   
  607.   signal (SIGINT, TerminateSearch);
  608.   side++;                /* shut up the compiler */
  609.   for (i = 4; i < 9; i++)
  610.     {
  611.       gotoXY (TAB, i);
  612.       ClrEoln ();
  613.     }
  614. }
  615.  
  616. void
  617. OutputMove (void)
  618. {
  619.   register int i, j, f, t;
  620.   char    *cp;
  621.  
  622.   if (root == NULL || GameCnt < 1)
  623.       return;
  624.   UpdateDisplay (root->f, root->t, 0, (short) root->flags);
  625.   cp = count_pieces(black);
  626.   gotoXY(TAB, 1);
  627.   printz(cp);
  628.   ClrEoln();
  629.   cp = count_pieces(white);
  630.   gotoXY(TAB, LINE_BOT_PIECES);
  631.   printz(cp);
  632.   ClrEoln();
  633.  
  634.   i = 0;
  635.   if (GameCnt) {
  636.       if (GameCnt < 6)
  637.           j = 1;
  638.       else
  639.           j = (GameCnt - 6) | 1;
  640.       for (; i < 3 && j <= GameCnt; ) {
  641.         gotoXY(TAB, 9 + i++);
  642.         f = GameList[j].gmove >> 8;
  643.         t = (GameList[j].gmove & 0xFF);
  644.         algbr (f, t, false);
  645.         printz("%2d: %s  ", (j + 1) / 2, mvstr[0]);
  646.         if (++j > GameCnt) {
  647.             ClrEoln();
  648.             break;
  649.             }
  650.         f = GameList[j].gmove >> 8;
  651.         t = (GameList[j++].gmove & 0xFF);
  652.         algbr (f, t, false);
  653.         printz("%s", mvstr[0]);
  654.           }
  655.     }
  656.    while (i < 3) {
  657.     gotoXY(TAB, 9 + i++);
  658.     ClrEoln();
  659.     }
  660.  
  661.   gotoXY (TAB, 12);
  662.   if (root->flags & draw)
  663.     printz ("Drawn game!");
  664.   else if (root->score == -9999)
  665.     printz ("Opponent mates!");
  666.   else if (root->score == 9998)
  667.     printz ("Computer mates!");
  668.   else if (root->score < -9000)
  669.     printz ("Opponent mates soon!");
  670.   else if (root->score > 9000)
  671.     printz ("Computer mates soon!");
  672.   ClrEoln ();
  673.  
  674.       ShowNodeCnt (NodeCnt, evrate);
  675.       gotoXY (TAB, LINE_MAX_TREE);
  676.       for (i = 1999; i >= 0 && Tree[i].f == 0 && Tree[i].t == 0; i--);
  677.       printz ("Max Tree=%d", i);
  678.       ClrEoln ();
  679. }
  680.  
  681. void
  682. ElapsedTime (short int iop)
  683.  
  684. /*
  685.   Determine the time that has passed since the search was started. If
  686.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  687.   timeout to true which will terminate the search.
  688. */
  689.  
  690. {
  691.   et = time ((long *) 0) - time0;
  692.   if (et < 0)
  693.     et = 0;
  694.   ETnodes += 50;
  695.   if (et > et0 || iop == 1)
  696.     {
  697.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  698.     flag.timeout = true;
  699.       et0 = et;
  700.       if (iop == 1)
  701.     {
  702.       time0 = time ((long *) 0);
  703.       et0 = 0;
  704.     }
  705.       if (et > 0)
  706.     /* evrate used to be Nodes / cputime I dont` know why */
  707.     evrate = NodeCnt / (et + ft);
  708.       else
  709.     evrate = 0;
  710.       ETnodes = NodeCnt + 50;
  711.       UpdateClocks ();
  712.     }
  713. }
  714.  
  715. void
  716. UpdateClocks (void)
  717. {
  718.   short m, s;
  719.   m = (short) (et / 60);
  720.   s = (short) (et - 60 * (long) m);
  721.   if (TCflag)
  722.     {
  723.       m = (short) ((TimeControl.clock[player] - et) / 60);
  724.       s = (short) (TimeControl.clock[player] - et - 60 * (long) m);
  725.     }
  726.   if (m < 0)
  727.     m = 0;
  728.   if (s < 0)
  729.     s = 0;
  730.   if (player == white)
  731.     gotoXY (TAB + 12, (flag.reverse) ? 0 : 15);
  732.   else
  733.     gotoXY (TAB + 12, (flag.reverse) ? 15 : 0);
  734.   printz ("%d:%02d", m, s);
  735.   ClrEoln ();
  736.     ShowNodeCnt (NodeCnt, evrate);
  737.   refresh ();
  738. }
  739.  
  740.  
  741. void
  742. SetTimeControl (void)
  743. {
  744.   if (TCflag)
  745.     {
  746.       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
  747.       TimeControl.clock[white] = TimeControl.clock[black] = 60 * (long) TCminutes;
  748.     }
  749.   else
  750.     {
  751.       TimeControl.moves[white] = TimeControl.moves[black] = 0;
  752.       TimeControl.clock[white] = TimeControl.clock[black] = 0;
  753.       Level = 60 * (long) TCminutes;
  754.     }
  755.   et = 0;
  756.   ElapsedTime (1);
  757. }
  758.  
  759. void
  760. gotoXY (short int x, short int y)
  761. {
  762.   putchar(ESC);
  763.   putchar('[');
  764.   param(y+1);
  765.   putchar(';');
  766.   param(x+1);
  767.   putchar('H');
  768.   ttcol = x;
  769.   ttrow = y;
  770. }
  771.  
  772. void
  773. ClrScreen (void)
  774. {    register int    i;
  775.  
  776.   G_Mode(G_GRAPHICS);
  777.   for (i = 0; i < MAX_LINES; )
  778.       ttwidth[i++] = 0;
  779. }
  780.  
  781. void
  782. ClrEoln (void)
  783. {    int    i;
  784.  
  785.     for (i = ttcol; i < ttwidth[ttrow]; i++)
  786.         putchar(' ');
  787.     if (i != ttcol)
  788.         gotoXY(ttcol, ttrow);
  789.     ttwidth[ttrow] = ttcol;
  790.   refresh ();
  791. }
  792.  
  793. void
  794. param(short n)
  795. {
  796.   if (n >= 10)
  797.     {
  798.     register short d, q;
  799.     q = n/10; d = n%10;
  800.     putchar(q + '0');
  801.     putchar(d + '0');
  802.   }
  803.   else
  804.     putchar(n + '0');
  805. }
  806.  
  807. void
  808. DrawPiece (short int sq)
  809. { int    p = board[sq];
  810.   int    row = VIR_R(sq);
  811.   int    col = VIR_C(sq);
  812.   int    iswhite = !Vblack(sq);
  813.  
  814.   switch (color[sq])
  815.     {
  816.     case black:
  817.         draw_piece(row, col,
  818.         iswhite ? b_on_w_piece[p] : b_on_b_piece[p]);
  819.     break;
  820.     case neutral:
  821.         draw_piece(row, col,
  822.         iswhite ? w_on_w_piece[0] : b_on_b_piece[0]);
  823.     break;
  824.     case white:
  825.         draw_piece(row, col,
  826.         iswhite ? w_on_w_piece[p] : w_on_b_piece[p]);
  827.     break;
  828.     default:
  829.       ShowMessage ("DrawPiece: error");
  830.       break;
  831.     }
  832. }
  833.  
  834. void
  835. DrawSquare (short int sq)
  836. {
  837.   int    iswhite = !Vblack(sq);
  838.   int    row = VIR_R(sq);
  839.   int    col = VIR_C(sq);
  840.  
  841.   draw_piece(row, col,
  842.         iswhite ? w_on_w_piece[0] : b_on_w_piece[0]);
  843. }
  844.  
  845. void
  846. DrawCoords (void)
  847. {
  848.   register short z;
  849.   char    buf[10];
  850.  
  851.   buf[1] = '\0';
  852.   for (z = 0; z <= 7; z++) {
  853.       buf[0] = (7 - z) + '1';
  854.     draw_small_string(0, 15 * z + 4, buf);
  855.     }
  856.  
  857.   for (z = 0; z <= 7; z++) {
  858.       buf[0] = z + 'A';
  859.       draw_small_string(15 * z + 10, MAX_Y - 6, buf);
  860.     }
  861. }
  862.  
  863. void
  864. UpdateDisplay (short int f, short int t, short int redraw, short int isspec)
  865. {
  866.   short sq;
  867.   
  868.   if (redraw)
  869.     {
  870.       ShowPlayers ();
  871.       for (sq = 0; sq < 64; sq++)
  872.     {
  873.       DrawSquare (sq);
  874.       DrawPiece (sq);
  875.     }
  876.       if (coords)
  877.     DrawCoords ();
  878.     }
  879.   else
  880.     {
  881.       DrawPiece (f);
  882.       DrawPiece (t);
  883.       if (isspec & cstlmask)
  884.     if (t > f)
  885.       {
  886.         DrawPiece (f + 3);
  887.         DrawPiece (t - 1);
  888.       }
  889.     else
  890.       {
  891.         DrawPiece (f - 4);
  892.         DrawPiece (t + 1);
  893.       }
  894.       else if (isspec & epmask)
  895.     {
  896.       DrawPiece (t - 8);
  897.       DrawPiece (t + 8);
  898.     }
  899.     }
  900.   refresh ();
  901. }
  902.  
  903. void
  904. GetGame (void)
  905. {
  906.   FILE *fd;
  907.   char fname[256], tname[256];
  908.   char *tmp;
  909.   int c;
  910.   short sq;
  911.   unsigned short m;
  912.  
  913.   tname[0] = 0;
  914.  
  915.   if (tmp = getenv ("HOME")) {
  916.     strcpy (fname, tmp);
  917.     strcat (fname, "/");
  918.     }
  919.   else
  920.     fname[0] = '\0';
  921.  
  922.   ShowMessage ("File name: ");
  923.   read_line(tname);
  924.  
  925.   if (tname[0])
  926.     strcat (fname, tname);
  927.   else
  928.     strcat (fname, "chess.000");
  929.  
  930.   ShowMessage("Loading ");
  931.   printz ("%s", fname);
  932.  
  933.   if ((fd = fopen (fname, "r")) == NULL)
  934.     {
  935.       ShowMessage ("Load failed");
  936.       return;
  937.     }
  938.  
  939.   fscanf (fd, "%hd%hd%hd", &computer, &opponent, &Game50);
  940.   fscanf (fd, "%hd%hd", &castld[white], &castld[black]);
  941.   fscanf (fd, "%hd%hd", &TCflag, &OperatorTime);
  942.   fscanf (fd, "%ld%ld%hd%hd",
  943.       &TimeControl.clock[white], &TimeControl.clock[black],
  944.       &TimeControl.moves[white], &TimeControl.moves[black]);
  945.   for (sq = 0; sq < 64; sq++)
  946.     {
  947.       fscanf (fd, "%hd%hd", &m, &Mvboard[sq]);
  948.       board[sq] = (m >> 8);
  949.       color[sq] = (m & 0xFF);
  950.       if (color[sq] == 0)
  951.     color[sq] = neutral;
  952.       else
  953.     --color[sq];
  954.     }
  955.   GameCnt = 0;
  956.   c = '?';
  957.   while (c != EOF)
  958.     {
  959.       ++GameCnt;
  960.       c = fscanf (fd, "%hd%hd%hd%ld%hd%hd%hd", &GameList[GameCnt].gmove,
  961.           &GameList[GameCnt].score, &GameList[GameCnt].depth,
  962.           &GameList[GameCnt].nodes, &GameList[GameCnt].time,
  963.           &GameList[GameCnt].piece, &GameList[GameCnt].color);
  964.       if (GameList[GameCnt].color == 0)
  965.     GameList[GameCnt].color = neutral;
  966.       else
  967.     --GameList[GameCnt].color;
  968.     }
  969.   GameCnt--;
  970.   if (TimeControl.clock[white] > 0)
  971.     TCflag = true;
  972.   computer--;
  973.   opponent--;
  974.  
  975.   fclose (fd);
  976.  
  977.   InitializeStats ();
  978.   Sdepth = 0;
  979.   ShowMessage ("Done.  Press <Ret>");
  980.   fflush (stdin);
  981.   getchar ();
  982.   UpdateDisplay (0, 0, 1, 0);
  983.  
  984. }
  985.  
  986. void
  987. SaveGame (void)
  988. {
  989.   FILE *fd;
  990.   char fname[256], tname[256];
  991.   char *tmp;
  992.   short sq, i, c;
  993.  
  994.   tname[0] = 0;
  995.  
  996.   if (tmp = getenv ("HOME")) {
  997.     strcpy (fname, tmp);
  998.     strcat (fname, "/");
  999.     }
  1000.   else
  1001.     fname[0] = '\0';
  1002.  
  1003.   ShowMessage ("File name: ");
  1004.   refresh ();
  1005.   read_line(tname);
  1006.  
  1007.   if (tname[0])
  1008.     strcat (fname, tname);
  1009.   else
  1010.     strcat (fname, "chess.000");
  1011.  
  1012.   ShowMessage("Saving ");
  1013.   printz ("%s", fname);
  1014.  
  1015.   if (NULL == (fd = fopen (fname, "w")))
  1016.     {
  1017.       ShowMessage ("Not saved");
  1018.       return;
  1019.     }
  1020.  
  1021.   fprintf (fd, "%d %d %d\n", computer + 1, opponent + 1, Game50);
  1022.   fprintf (fd, "%d %d\n", castld[white], castld[black]);
  1023.   fprintf (fd, "%d %d\n", TCflag, OperatorTime);
  1024.   fprintf (fd, "%ld %ld %d %d\n",
  1025.        TimeControl.clock[white], TimeControl.clock[black],
  1026.        TimeControl.moves[white], TimeControl.moves[black]);
  1027.   for (sq = 0; sq < 64; sq++)
  1028.     {
  1029.       if (color[sq] == neutral)
  1030.     c = 0;
  1031.       else
  1032.     c = color[sq] + 1;
  1033.       fprintf (fd, "%d %d\n", 256 * board[sq] + c, Mvboard[sq]);
  1034.     }
  1035.   for (i = 1; i <= GameCnt; i++)
  1036.     {
  1037.       if (GameList[i].color == neutral)
  1038.     c = 0;
  1039.       else
  1040.     c = GameList[i].color + 1;
  1041.       fprintf (fd, "%d %d %d %ld %d %d %d\n",
  1042.            GameList[i].gmove, GameList[i].score, GameList[i].depth,
  1043.            GameList[i].nodes, GameList[i].time,
  1044.            GameList[i].piece, c);
  1045.     }
  1046.   fclose (fd);
  1047.   ShowMessage ("Done.  Press <Ret>");
  1048.   fflush (stdin);
  1049.   getchar ();
  1050. }
  1051.  
  1052. void
  1053. ListGame (void)
  1054. {
  1055.   FILE *fd;
  1056.   char fname[256];
  1057.   char *tmp;
  1058.   short i, f, t;
  1059.  
  1060.   if (tmp = getenv ("HOME")) {
  1061.     strcpy (fname, tmp);
  1062.     strcat(fname, "/");
  1063.     }
  1064.   else
  1065.     fname[0] = '\0';
  1066.   strcat (fname, "chess.lst");
  1067.  
  1068.   if (fd = fopen (fname, "w"))
  1069.     ShowMessage ("Writing chess.lst");
  1070.   else
  1071.     {
  1072.       ShowMessage ("Cannot write chess.lst");
  1073.       return;
  1074.     }
  1075.  
  1076.   fprintf (fd, "\n");
  1077.   fprintf (fd, "       score  depth   nodes  time         ");
  1078.   fprintf (fd, "       score  depth   nodes  time\n");
  1079.   for (i = 1; i <= GameCnt; i++)
  1080.     {
  1081.       f = GameList[i].gmove >> 8;
  1082.       t = (GameList[i].gmove & 0xFF);
  1083.       algbr (f, t, false);
  1084.       if (i & 1)
  1085.     fprintf (fd, "\n");
  1086.       else
  1087.     fprintf (fd, "         ");
  1088.       fprintf (fd, "%5s  %5d     %2d %7ld %5d", mvstr[0],
  1089.            GameList[i].score, GameList[i].depth,
  1090.            GameList[i].nodes, GameList[i].time);
  1091.     }
  1092.   fprintf (fd, "\n\n");
  1093.   fclose (fd);
  1094.   ShowMessage ("chess.lst written");
  1095. }
  1096.  
  1097. void
  1098. Undo (void)
  1099.  
  1100. /*
  1101.   Undo the most recent half-move.
  1102. */
  1103.  
  1104. {
  1105.   short f, t;
  1106.   f = GameList[GameCnt].gmove >> 8;
  1107.   t = GameList[GameCnt].gmove & 0xFF;
  1108.   if (board[t] == king && distance (t, f) > 1)
  1109.     (void) castle (GameList[GameCnt].color, f, t, 2);
  1110.   else
  1111.     {
  1112.       /* Check for promotion: */
  1113.       if ((color[t] == white && row (f) == 6 && row (t) == 7)
  1114.       || (color[t] == black && row (f) == 1 && row (t) == 0))
  1115.     {
  1116.       int g, from = f;
  1117.       for (g = GameCnt - 1; g > 0; g--)
  1118.         if (GameList[g].gmove & 0xFF == from)
  1119.           from = GameList[g].gmove >> 8;
  1120.       if ((color[t] == white && row (from) == 1)
  1121.           || (color[t] == black && row (from) == 6))
  1122.         board[t] = pawn;
  1123.     }
  1124.       board[f] = board[t];
  1125.       color[f] = color[t];
  1126.       board[t] = GameList[GameCnt].piece;
  1127.       color[t] = GameList[GameCnt].color;
  1128.       if (color[t] != neutral)
  1129.     Mvboard[t]--;
  1130.       Mvboard[f]--;
  1131.     }
  1132.   if (TCflag)
  1133.     ++TimeControl.moves[color[f]];
  1134.   GameCnt--;
  1135.   computer = otherside[computer];
  1136.   opponent = otherside[opponent];
  1137.   flag.mate = false;
  1138.   Sdepth = 0;
  1139.   UpdateDisplay (0, 0, 1, 0);
  1140.   InitializeStats ();
  1141.   OutputMove();
  1142. }
  1143.  
  1144. void
  1145. ChangeAlphaWindow (void)
  1146. {
  1147.   ShowMessage ("Awindow= ");
  1148.   Awindow = read_number(Awindow);
  1149. }
  1150.  
  1151. void
  1152. ChangeBetaWindow (void)
  1153. {
  1154.   ShowMessage ("Bwindow= ");
  1155.   Bwindow = read_number(Bwindow);
  1156. }
  1157.  
  1158. void
  1159. GiveHint (void)
  1160. {
  1161.   char s[40];
  1162.   algbr ((short) (hint >> 8), (short) (hint & 0xFF), false);
  1163.   strcpy (s, "try ");
  1164.   strcat (s, mvstr[0]);
  1165.   ShowMessage (s);
  1166. }
  1167.  
  1168. void
  1169. ChangeSearchDepth (void)
  1170. {
  1171.   ShowMessage ("depth= ");
  1172.   MaxSearchDepth = read_number(MaxSearchDepth);
  1173. }
  1174.  
  1175. void
  1176. SetContempt (void)
  1177. {
  1178.   ShowMessage ("contempt= ");
  1179.   contempt = read_number(contempt);
  1180. }
  1181.  
  1182. void
  1183. ChangeXwindow (void)
  1184. {
  1185.   ShowMessage ("xwndw= ");
  1186.   xwndw = read_number(xwndw);
  1187. }
  1188.  
  1189. void
  1190. SelectLevel (void)
  1191. {
  1192. static struct {
  1193.     int    moves;
  1194.     int    minutes;
  1195.     } tbl[] = {
  1196.     {60, 5},
  1197.     {60, 15},
  1198.     {60, 30},
  1199.     {40, 30},
  1200.     {40, 60},
  1201.     {40, 120},
  1202.     {40, 240},
  1203.     {1, 15},
  1204.     {1, 60},
  1205.     {1, 600}
  1206.     };
  1207.  
  1208.   ClrScreen ();
  1209.   gotoXY (12, 0);
  1210.   printz (  "GNU CHESS v3.1");
  1211.   gotoXY (10, 1);
  1212.   printz ("ported by Paul Fox");
  1213.   gotoXY (4, 4);
  1214.   printz (" 1.   60 moves in   5 minutes");
  1215.   gotoXY (4, 5);
  1216.   printz (" 2.   60 moves in  15 minutes");
  1217.   gotoXY (4, 6);
  1218.   printz (" 3.   60 moves in  30 minutes");
  1219.   gotoXY (4, 7);
  1220.   printz (" 4.   40 moves in  30 minutes");
  1221.   gotoXY (4, 8);
  1222.   printz (" 5.   40 moves in  60 minutes");
  1223.   gotoXY (4, 9);
  1224.   printz (" 6.   40 moves in 120 minutes");
  1225.   gotoXY (4, 10);
  1226.   printz (" 7.   40 moves in 240 minutes");
  1227.   gotoXY (4, 11);
  1228.   printz (" 8.    1 move  in  15 minutes");
  1229.   gotoXY (4, 12);
  1230.   printz (" 9.    1 move  in  60 minutes");
  1231.   gotoXY (4, 13);
  1232.   printz ("10.    1 move  in 600 minutes");
  1233.  
  1234.   OperatorTime = 1;
  1235.   TCmoves = 60;
  1236.   TCminutes = 5;
  1237.  
  1238.   gotoXY (4, 15);
  1239.   printz ("Enter Level: ");
  1240.   refresh ();
  1241.   Level = read_number(Level) - 1;
  1242.   if (Level >= 0 && Level < sizeof tbl / sizeof tbl[0]) {
  1243.       TCmoves = tbl[Level].moves;
  1244.       TCminutes = tbl[Level].minutes;
  1245.       }
  1246.  
  1247.   TCflag = (TCmoves > 1);
  1248.   SetTimeControl ();
  1249.   ClrScreen ();
  1250.   UpdateDisplay (0, 0, 1, 0);
  1251. }
  1252. void
  1253. ShowPostnValue (short int sq)
  1254.  
  1255. /*
  1256.   must have called ExaminePosition() first
  1257. */
  1258.      
  1259. { int    x, y;
  1260.   char buf[10];
  1261.   short score;
  1262.   
  1263.   x = VIR_C(sq) * 15;
  1264.   y = VIR_R(sq) * 15;
  1265.   ScorePosition (color[sq], &score);
  1266.  
  1267.   if (color[sq] != neutral) {
  1268.     sprintf (buf, "%3d", svalue[sq]);
  1269.     draw_small_string(x + 7, y + 1, buf);
  1270.     }
  1271. }
  1272.  
  1273. void
  1274. ShowPostnValues (void)
  1275. {
  1276.   short sq, score;
  1277.  
  1278.   ExaminePosition ();
  1279.   for (sq = 0; sq < 64; sq++)
  1280.     ShowPostnValue (sq);
  1281.   ScorePosition (opponent, &score);
  1282.   ShowScore (score);
  1283. }
  1284.  
  1285. void
  1286. DoDebug (void)
  1287. {
  1288.   short c, p, sq, tp, tc, tsq, score;
  1289.   char s[40];
  1290.   
  1291.   ExaminePosition ();
  1292.   ShowMessage ("Enter piece: ");
  1293.   read_line(s);
  1294.   c = neutral;
  1295.   if (s[0] == 'w' || s[0] == 'W')
  1296.     c = white;
  1297.   if (s[0] == 'b' || s[0] == 'B')
  1298.     c = black;
  1299.   for(p = king; p > no_piece; p--)
  1300.     if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
  1301.       break;
  1302.   for (sq = 0; sq < 64; sq++)
  1303.     {
  1304.       tp = board[sq];
  1305.       tc = color[sq];
  1306.       board[sq] = p;
  1307.       color[sq] = c;
  1308.       tsq = PieceList[c][1];
  1309.       PieceList[c][1] = sq;
  1310.       ShowPostnValue (sq);
  1311.       PieceList[c][1] = tsq;
  1312.       board[sq] = tp;
  1313.       color[sq] = tc;
  1314.     }
  1315.   ScorePosition (opponent, &score);
  1316.   ShowScore (score);
  1317. }
  1318.  
  1319. void
  1320. TestSpeed(void (*f) (short int side, short int ply))
  1321. {
  1322.   short i;
  1323.   long t1, t2;
  1324.  
  1325.   t1 = time (0);
  1326.   for (i = 0; i < 1000; i++)
  1327.     {
  1328.       f (opponent, 2);
  1329.     }
  1330.   t2 = time (0);
  1331.   NodeCnt = 1000L * (TrPnt[3] - TrPnt[2]);
  1332.   evrate = NodeCnt / (t2 - t1);
  1333.   ShowNodeCnt (NodeCnt, evrate);
  1334. }
  1335.  
  1336. void
  1337. InputCommand (void)
  1338.  
  1339. /*
  1340.   Process the users command. If easy mode is OFF (the computer is thinking
  1341.   on opponents time) and the program is out of book, then make the 'hint'
  1342.   move on the board and call SelectMove() to find a response. The user
  1343.   terminates the search by entering ^C (quit siqnal) before entering a
  1344.   command. If the opponent does not make the hint move, then set Sdepth to
  1345.   zero.
  1346. */
  1347.  
  1348. {
  1349.   short ok, tmp;
  1350.   unsigned short mv;
  1351.   char s[80];
  1352.  
  1353.   ok = flag.quit = false;
  1354.   player = opponent;
  1355.   ShowSidetomove ();
  1356.   ft = 0;
  1357.   if (hint > 0 && !flag.easy && Book == NULL)
  1358.     {
  1359.       fflush (stdout);
  1360.       time0 = time ((long *) 0);
  1361.       algbr ((short) hint >> 8, (short) hint & 0xFF, false);
  1362.       strcpy (s, mvstr[0]);
  1363.       tmp = epsquare;
  1364.       if (VerifyMove (s, 1, &mv))
  1365.     {
  1366.       ShowPrompt ();
  1367.       SelectMove (computer, 2);
  1368.       (void) VerifyMove (mvstr[0], 2, &mv);
  1369.       if (Sdepth > 0)
  1370.         Sdepth--;
  1371.     }
  1372.       ft = time ((long *) 0) - time0;
  1373.       epsquare = tmp;
  1374.     }
  1375.   signal (SIGINT, Die);
  1376. #ifndef MSDOS
  1377.   signal (SIGQUIT, Die);
  1378. #endif /* MSDOS */
  1379.   while (!(ok || flag.quit))
  1380.     {
  1381.       ShowPrompt ();
  1382.       read_line(s);
  1383.       player = opponent;
  1384.       ok = VerifyMove (s, 0, &mv);
  1385.       if (ok)
  1386.           OutputMove();
  1387.       if (ok && mv != hint)
  1388.     {
  1389.       Sdepth = 0;
  1390.       ft = 0;
  1391.     }
  1392.       if (*s == '\0')
  1393.     UpdateDisplay (0, 0, 1, 0);
  1394.       if (strcmp (s, "bd") == 0)
  1395.     {
  1396.       ClrScreen ();
  1397.       UpdateDisplay (0, 0, 1, 0);
  1398.       ShowSidetomove();
  1399.     }
  1400.       if ((strcmp (s, "quit") == 0) || (strcmp (s, "exit") == 0))
  1401.     flag.quit = true;
  1402.       if (strcmp (s, "post") == 0)
  1403.     flag.post = !flag.post;
  1404.       if (strcmp (s, "edit") == 0)
  1405.     EditBoard ();
  1406.       if (strcmp (s, "go") == 0)
  1407.     ok = true;
  1408.       if (strcmp (s, "help") == 0)
  1409.     help ();
  1410.       if (strcmp (s, "force") == 0)
  1411.     flag.force = !flag.force;
  1412.       if (strcmp (s, "book") == 0)
  1413.     Book = NULL;
  1414.       if (strcmp (s, "undo") == 0 && GameCnt > 0)
  1415.     Undo ();
  1416.       if (strcmp (s, "new") == 0)
  1417.     NewGame ();
  1418.       if (strcmp (s, "list") == 0)
  1419.     ListGame ();
  1420.       if (strcmp (s, "level") == 0)
  1421.     SelectLevel ();
  1422.       if (strcmp (s, "hash") == 0)
  1423.     flag.hash = !flag.hash;
  1424.       if (strcmp (s, "beep") == 0)
  1425.     flag.beep = !flag.beep;
  1426.       if (strcmp (s, "Awindow") == 0)
  1427.     ChangeAlphaWindow ();
  1428.       if (strcmp (s, "Bwindow") == 0)
  1429.     ChangeBetaWindow ();
  1430.       if (strcmp (s, "hint") == 0)
  1431.     GiveHint ();
  1432.       if (strcmp (s, "both") == 0)
  1433.     {
  1434.       flag.bothsides = !flag.bothsides;
  1435.       Sdepth = 0;
  1436.       SelectMove (opponent, 1);
  1437.       ok = true;
  1438.     }
  1439.       if (strcmp (s, "reverse") == 0)
  1440.     {
  1441.       flag.reverse = !flag.reverse;
  1442.       ClrScreen ();
  1443.       UpdateDisplay (0, 0, 1, 0);
  1444.     }
  1445.       if (strcmp (s, "switch") == 0)
  1446.     {
  1447.       computer = otherside[computer];
  1448.       opponent = otherside[opponent];
  1449.       flag.force = false;
  1450.       Sdepth = 0;
  1451.       ok = true;
  1452.     }
  1453.       if (strcmp (s, "white") == 0)
  1454.     {
  1455.       computer = white;
  1456.       opponent = black;
  1457.       ok = true;
  1458.       flag.force = false;
  1459.       Sdepth = 0;
  1460.     }
  1461.       if (strcmp (s, "black") == 0)
  1462.     {
  1463.       computer = black;
  1464.       opponent = white;
  1465.       ok = true;
  1466.       flag.force = false;
  1467.       Sdepth = 0;
  1468.     }
  1469.       if (strcmp (s, "remove") == 0 && GameCnt > 1)
  1470.     {
  1471.       Undo ();
  1472.       Undo ();
  1473.     }
  1474.       if (strcmp (s, "get") == 0)
  1475.     GetGame ();
  1476.       if (strcmp (s, "save") == 0)
  1477.     SaveGame ();
  1478.       if (strcmp (s, "depth") == 0)
  1479.     ChangeSearchDepth ();
  1480.       if (strcmp (s, "random") == 0)
  1481.     dither = 6;
  1482.       if (strcmp (s, "easy") == 0)
  1483.     flag.easy = !flag.easy;
  1484.       if (strcmp (s, "contempt") == 0)
  1485.     SetContempt ();
  1486.       if (strcmp (s, "xwndw") == 0)
  1487.     ChangeXwindow ();
  1488.       if (strcmp (s, "coords") == 0)
  1489.     {
  1490.       coords = !coords;
  1491.       UpdateDisplay (0, 0, 1, 0);
  1492.     }
  1493.       if (strcmp (s, "test") == 0)
  1494.     {
  1495.           ShowMessage("MoveList speed test");
  1496.       TestSpeed (MoveList);
  1497.           ShowMessage("CaptureList speed");
  1498.       TestSpeed (CaptureList);
  1499.     }
  1500.       if (strcmp (s, "p") == 0)
  1501.     ShowPostnValues ();
  1502.  
  1503.       if (strcmp (s, "debug") == 0)
  1504.     DoDebug ();
  1505.     }
  1506.  
  1507.   ClearMessage ();
  1508.   ElapsedTime (1);
  1509.   if (flag.force)
  1510.     {
  1511.       computer = opponent;
  1512.       opponent = otherside[computer];
  1513.     }
  1514.   signal (SIGINT, TerminateSearch);
  1515. }
  1516. void
  1517. draw_bitmap(x, y, p)
  1518. int    x, y;
  1519. char    *p;
  1520. {
  1521.     G_ImagePut(x, y, p, G_FORCE);
  1522. }
  1523. void
  1524. draw_piece(r, c, p)
  1525. int    r, c;
  1526. struct bitmap *p;
  1527. {
  1528.     draw_bitmap(c * 15 + 5, (7 - r) * 15, p);
  1529. }
  1530. # define ARGS     a, b, c, d, e, f, g, h
  1531. printz(ARGS)
  1532. long    ARGS;
  1533. {    char    buf[80];
  1534.  
  1535.     sprintf(buf, ARGS);
  1536.     printf("%s", buf);
  1537.     ttcol += strlen(buf);
  1538.     if (ttcol > ttwidth[ttrow])
  1539.         ttwidth[ttrow] = ttcol;
  1540. }
  1541.  
  1542.  
  1543.